package com.leinao.tensorboard.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.leinao.commons.Response;
import com.leinao.config.EnvironmentConfig;
import com.leinao.constant.Constant;
import com.leinao.constant.ProjectJobHandleEnum;
import com.leinao.job.dto.PaiProjectJobDto;
import com.leinao.tensorboard.dao.TensorboardMapper;
import com.leinao.tensorboard.model.Tensorboard;
import com.leinao.tensorboard.service.TensorboardService;
import com.leinao.util.random.RandomPrimaryCode;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.List;

/**
 * @Author: huopengfei
 * @Date: 2019/5/21 10:39
 * @Description:
 * @Version 1.0
 */
@Service
public class TensorboardServiceImpl implements TensorboardService {

    private static Logger logger = LoggerFactory.getLogger(TensorboardServiceImpl.class);

    @Autowired
    private TensorboardMapper tensorboardMapper;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private EnvironmentConfig env;

    /**
      * 功能描述: 创建容器
      * @param userId
      * @param jobId
      * @Return:com.leinao.commons.Response<java.lang.String>
      * @Author:HuoPengfei
      * @Date:2019/5/21 11:13
      */
    @Override
    public Response<String> createContainer(String userId, Long jobId) {
        String domainUrl = tensorboardMapper.getDomainUrlByJobId(jobId);

        if(StringUtils.isNotEmpty(domainUrl)){
            return Response.ok(Constant.RESPONSE_STATUS_SUCCESS,ProjectJobHandleEnum.STARTUP_SUCCESS.getSeq(),ProjectJobHandleEnum.STARTUP_SUCCESS.getDesc(),domainUrl);
        }
        //获取output路径
        PaiProjectJobDto job = tensorboardMapper.getConfig(jobId);
        if(null==job||StringUtils.isEmpty(job.getProjectName())||null==job.getCodeNo()){
            return Response.error(Constant.RESPONSE_STATUS_SUCCESS,ProjectJobHandleEnum.NOT_FIND_OUTPUTS_PATH.getSeq(),ProjectJobHandleEnum.NOT_FIND_OUTPUTS_PATH.getDesc(),null);
        }
        // 路径改为/projects/#{userId}/#{projectName}/outputs/#{codeNo}
        String output = "/projects/"+userId+"/"+job.getProjectName()+"/outputs/"+job.getCodeNo();
        logger.info("***tensorboard-outputdir:" + output);
        String ip = "";
        String port = "";
        String container_id ="";

        if(StringUtils.isNotEmpty(output)){
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
            JSONObject jsonObj = new JSONObject();
            jsonObj.put("log_path",output);
            HttpEntity<String> formEntity = new HttpEntity<String>(jsonObj.toString(), headers);
            String conResponse ="";
            try {
                conResponse = restTemplate.postForObject(env.getTensorboardUrl(),formEntity,String.class);
            }catch (Exception e){
                e.printStackTrace();
                logger.error("调用tensorboardCreate创建失败(python)",e);
                return Response.error(Constant.RESPONSE_STATUS_SUCCESS, ProjectJobHandleEnum.TENSORBOARD_START_FAIL.getSeq(),ProjectJobHandleEnum.TENSORBOARD_START_FAIL.getDesc(),null);

            }
            if(StringUtils.isNotEmpty(conResponse)){
                JSONObject jsonObject = JSON.parseObject(conResponse);
                String status = (String) jsonObject.get("status");
                if("Success".equals(status)){
                    container_id = jsonObject.getString("container_id");
                    ip = jsonObject.getString("ip");
                    port = jsonObject.getInteger("port").toString();
                }else{
                    // return Response.error("tensorboard启动失败");
                    return Response.error(Constant.RESPONSE_STATUS_SUCCESS, ProjectJobHandleEnum.TENSORBOARD_START_FAIL.getSeq(),ProjectJobHandleEnum.TENSORBOARD_START_FAIL.getDesc(),null);
                }
            }else{
                return Response.error(Constant.RESPONSE_STATUS_SUCCESS, ProjectJobHandleEnum.TENSORBOARD_START_FAIL.getSeq(),ProjectJobHandleEnum.TENSORBOARD_START_FAIL.getDesc(),null);
                //return Response.error("tensorboard启动失败");
            }
        }else {
            //return Response.error("无法获取输出目录");
            return Response.error(Constant.RESPONSE_STATUS_SUCCESS,ProjectJobHandleEnum.NOT_FIND_OUTPUTS_PATH.getSeq(),ProjectJobHandleEnum.NOT_FIND_OUTPUTS_PATH.getDesc(),null);
        }

        String domain = RandomPrimaryCode.getPrimaryCode(8).toLowerCase() + env.getTensorboardDomain();

        Tensorboard tensorboard = new Tensorboard();
        tensorboard.setUserId(userId);
        tensorboard.setIp(ip);
        tensorboard.setPort(port);
        tensorboard.setVid(container_id);
        tensorboard.setDomain(domain);
        tensorboard.setJobId(jobId);
        //入库
        tensorboardMapper.createContainer(tensorboard);
        //TODO 调用户中心
        String nginxRes = restTemplate.postForObject(env.getUserCenterTsbUrl() + "tensorboard/reloadNginx",null,String.class);
        if(StringUtils.isNotEmpty(nginxRes)) {
            JSONObject jsonObject = JSON.parseObject(nginxRes);
            Integer statusCode = jsonObject.getInteger("code");
            if(statusCode == 0){
                return Response.ok(Constant.RESPONSE_STATUS_SUCCESS,ProjectJobHandleEnum.STARTUP_SUCCESS.getSeq(),ProjectJobHandleEnum.STARTUP_SUCCESS.getDesc(),domain);
            }
        }
        return Response.error(Constant.RESPONSE_STATUS_SUCCESS,ProjectJobHandleEnum.TRY_AGAIN.getSeq(),ProjectJobHandleEnum.TRY_AGAIN.getDesc(),null);
    }
    @Override
    public void deleteContainerAuto() {
        List<String> containerIds = tensorboardMapper.getTimeOutConId();
        if(containerIds == null || containerIds.size() == 0){
            logger.info("未找到超时的Tensorboard");
            return ;
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        JSONObject jsonObj = new JSONObject();
        jsonObj.put("container_ids",containerIds);
        HttpEntity<String> formEntity = new HttpEntity<String>(jsonObj.toString(), headers);
        try {
            restTemplate.exchange(env.getTensorboardUrl(), HttpMethod.DELETE,formEntity,String.class);
        }catch (Exception e){
            e.printStackTrace();
            logger.error("调用tensorboard销毁失败(python)",e);
            return;
        }
        tensorboardMapper.deleteTimeOutConById(containerIds);
        String nginxRes = restTemplate.postForObject(env.getUserCenterTsbUrl() + "tensorboard/reloadNginx",null,String.class);
        if(StringUtils.isNotEmpty(nginxRes)) {
            JSONObject jsonObject = JSON.parseObject(nginxRes);
            Integer statusCode = jsonObject.getInteger("code");
            if(statusCode == 0){
                logger.info("nginx文件修改成功");
            }else{
                logger.error("nginx文件修改失败");
            }
        }else{
            logger.error("nginx文件修改失败");
        }
    }
}
